package com.dhcc.DRGsHosp.infra.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.map.ObjectMapper;

import com.dhcc.DRGsHosp.core.domain.GroupingLog;

public class NotInGroupReasonUtil {
	
	public static String notInGroupReason(String mrInfoJson, String groupResultJson, String verDesc){
		ObjectMapper objectMapper = new ObjectMapper();
		NotInGroupReasonUtil res=new NotInGroupReasonUtil();  
		String notInGroupFlag="";
		try {
			Map<String, Object> groupResult = objectMapper.readValue(groupResultJson, Map.class);
			Map<String,Object> mrInfoMap=objectMapper.readValue(mrInfoJson, Map.class);
			
			//判断是否入组
			if (!groupResult.get("drg").toString().matches("^\\w{1,2}QY$")&&!groupResult.get("drg").toString().matches("^\\d{4}$")) {
				return "{\"error\": false,\"error_log\": \"\",\"notInGroupReason\":\"0\"}";
			}
			if(verDesc!=null&&verDesc.indexOf("北京2016版")>=0){
				notInGroupFlag=res.notInGroupReasonCode2016(mrInfoMap,groupResult);//2016版分组器未入组原因判断
			}
			else if("北京2015版".equals(verDesc)||"CC2015版".equals(verDesc)){
				notInGroupFlag=res.notInGroupReasonCode2015(groupResult);
			}
			else{
				return "{\"error\": true,\"error_log\": \"无效版本号\",\"notInGroupReason\":\"\"}";
			}
			return "{\"error\": false,\"error_log\": \"\",\"notInGroupReason\":\""+notInGroupFlag+"\"}";
		} catch (Exception e) {
			e.printStackTrace();
			return "{\"error\": true,\"error_log\": \""+e.toString()+"\",\"notInGroupReason\":\"o_other\"}";
		}
	}
	private String notInGroupReasonCode2015(Map<String, Object> groupResult) {
		String notInGroupFlag = "o_other";//默认为其他
		GroupingLog groupingLog = new GroupingLog();
		String index = "";
		Class<GroupingLog> groupLogClass = GroupingLog.class;
        Field field = null;
		if(groupResult.get("log")!=null){
        	@SuppressWarnings("unchecked")
			List<String> logList=(List<String>)groupResult.get("log");
        	for (String string :logList) {
        		index = string.replaceAll("^判断(\\d\\d)(\\.(\\d))?(\\.(\\d))?：.*$", "$1$3$5");
        		index = index.replaceAll("^判断(\\d)(\\.(\\d))?(\\.(\\d))?：.*$", "0$1$3$5");
        		try {
        			field = groupLogClass.getDeclaredField("glJ" + index);
        			field.setAccessible(true);
    				field.set(groupingLog, string);
        		} catch (Exception e) {
        			e.printStackTrace();
        		}
			}
        	// 判断未入组原因
    		String gl00 = groupingLog.getGlJ00();
    		String gl01 = groupingLog.getGlJ01();
    		String gl02 = groupingLog.getGlJ02();
    		String gl03 = groupingLog.getGlJ03();
    		String gl04 = groupingLog.getGlJ04();
    		String gl05 = groupingLog.getGlJ05();
    		String gl06 = groupingLog.getGlJ06();
    		String gl07 = groupingLog.getGlJ07();
    		String gl08 = groupingLog.getGlJ08();
    		String gl081 = groupingLog.getGlJ081();
    		String gl09 = groupingLog.getGlJ09();
    		String gl091 = groupingLog.getGlJ091();
    		String gl101 = groupingLog.getGlJ101();
    		String gl102 = groupingLog.getGlJ102();
    		String gl103 = groupingLog.getGlJ103();
    		String gl104 = groupingLog.getGlJ104();
    		String gl1040 = groupingLog.getGlJ1040();
    		String gl105 = groupingLog.getGlJ105();
    		String gl106 = groupingLog.getGlJ106();
    		String gl11 = groupingLog.getGlJ11();
    		int adrgcount = 0;//判断l04中返回的adrg代码是否在adrg列表，0表示无
    		String[] adrgstr;
    		if (gl04 != null&& gl04.length()>18) {
    			String[] drgs = gl04.substring(18, gl04.length()).split(",");
    			if(drgs.length>0){
    				//读取文件
    				List<String> adrgList=new ArrayList<String>();
    				try {
    					InputStream ips = this.getClass().getResourceAsStream("/operationdrg.txt");
    					InputStreamReader isr=new InputStreamReader(ips, "UTF-8");
    					BufferedReader br = new BufferedReader(isr);
    					String line="";
    					while ((line=br.readLine())!=null) {
    						adrgList.add(line);
    					}
    					br.close();
    					isr.close();
    					ips.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				//读取文件
    		        for (int o = 0; o < drgs.length; o++) {
    		        	if(adrgList.contains(drgs[o])){
    		        		adrgcount=1;
    		        		break;
    		        	}
        			}
    			}
    		}
    		// 具体6大判断规则
    		if (gl11 != null && "QY".equals(gl11.substring(gl11.length() - 2, gl11.length()))) {
    			notInGroupFlag = "q_qY";
    		} 
    		else if (gl00 != null && !"".equals(gl00.substring(15, gl00.length())) && gl11 != null && "9999".equals(gl11.substring(gl11.length() - 4, gl11.length()))) {
    			notInGroupFlag = "c_costOrDay";//住院日或费用异常
    		} 
    		else if (gl01 != null && "null".equals(gl01.substring(gl01.length() - 4, gl01.length()))) {
    			notInGroupFlag = "md_noMDiag";
    		} 
    		else if ((gl00 == null && gl01 != null && gl01.substring(13, gl01.length()) != "" && gl01.substring(13, gl01.length()) != null && gl02 == null && gl03 == null && gl04 == null && gl05 == null && gl06 == null && gl07 == null && gl08 == null && gl081 == null && gl09 == null && gl091 == null && gl101 == null && gl102 == null && gl103 == null && gl104 == null && gl1040 == null && gl105 == null && gl106 == null && gl11 != null && "0000".equals(gl11.substring(gl11.length() - 4, gl11.length()))) || (gl03 != null && "".equals(gl03.substring(14, gl03.length())) && adrgcount != 0)) {
    			notInGroupFlag = "md_diagOtherReason";//主要诊断有误
    		} 
    		else if (gl04 != null) {
    			adrgstr = gl04.substring(18, gl04.length()).split(",");
    			int gl4fg = 0;
    			for (int j = 0; j < adrgstr.length; j++) {
    				if ("P".equals(adrgstr[j].substring(0, 1))) {
    					gl4fg++;
    				}
    			}
    			if (gl4fg != 0) {
    				notInGroupFlag = "n_ageOrWeightEtcErr";
    			} else {
    				notInGroupFlag = "o_other";
    			}
    		}
    		else {
    			notInGroupFlag = "o_other";
    		}
        }
		return notInGroupFlag;
	}
	private String notInGroupReasonCode2016(Map<String, Object> mrInfoMap,Map<String, Object> groupResult) {
		String notInGroupFlag="o_other";
		if("null".equals(mrInfoMap.get("DISEASE_CODE")+"")||!StringUtils.hasLength(mrInfoMap.get("DISEASE_CODE")+"")){//主要诊断缺失
			notInGroupFlag="md_noMDiag";
			return notInGroupFlag;
		}
		else if(mrInfoMap.get("DISEASE_CODE").toString().length()<=6){//无效的主要诊断编码
			notInGroupFlag="md_invalidMainDiag";
			return notInGroupFlag;
		}
		else if(groupResult.get("drg")!=null&&groupResult.get("drg").toString().contains("QY")){//手术/操作与诊断不符
			notInGroupFlag="q_qY";
			return notInGroupFlag;
		}
		else if(groupResult.get("drg")!=null&&"9999".equals(groupResult.get("drg").toString())){//费用住院日异常
			if((mrInfoMap.get("ACCTUAL_DAYS")==null||Integer.valueOf(mrInfoMap.get("ACCTUAL_DAYS").toString())>60)&&(mrInfoMap.get("TOTAL_EXPENSE")==null||Double.valueOf(mrInfoMap.get("TOTAL_EXPENSE").toString())<4)){//费用和住院日均异常
				notInGroupFlag="c_costAndDay";
				return notInGroupFlag;
			}
			else if(mrInfoMap.get("TOTAL_EXPENSE")==null||Double.valueOf(mrInfoMap.get("TOTAL_EXPENSE").toString())<4){//费用异常
				notInGroupFlag="c_cost";
				return notInGroupFlag;
			}
			else{
				notInGroupFlag="c_day";
				return notInGroupFlag;
			}
		}
		else if(groupResult.get("drg")!=null&&"0000".equals(groupResult.get("drg").toString())){//
			//主要诊断不标准
			if(groupResult.get("error")!=null&&"true".equals(String.valueOf(groupResult.get("error")))&&groupResult.get("error_log")!=null&&"主要诊断不标准！".equals(groupResult.get("error_log"))){//主要诊断编码不在北京临床版范围内
				notInGroupFlag="md_diagOutOfRange";
				return notInGroupFlag;
			}
			//字段类型或值有误
			if(groupResult.get("error")!=null&&"true".equals(String.valueOf(groupResult.get("error")))&&groupResult.get("error_log")!=null&&"判断00：字段类型或值有误;".equals(groupResult.get("error_log"))){
				if((mrInfoMap.get("ACCTUAL_DAYS")==null)&&(mrInfoMap.get("TOTAL_EXPENSE")==null)){//费用和住院日均异常
					notInGroupFlag="c_costAndDay";
					return notInGroupFlag;
				}
				else if(mrInfoMap.get("TOTAL_EXPENSE")==null){//费用异常
					notInGroupFlag="c_cost";
					return notInGroupFlag;
				}
				else if(mrInfoMap.get("ACCTUAL_DAYS")==null){//住院日异常
					notInGroupFlag="c_day";
					return notInGroupFlag;
				}
				else{
					notInGroupFlag="o_other";
					return notInGroupFlag;
				}
			}
			if(groupResult.get("error")!=null&&"true".equals(String.valueOf(groupResult.get("error")))){//其他原因
				notInGroupFlag="o_other";
				return notInGroupFlag;
			}
			if(groupResult.get("mdcs_main")!=null&&"[]".equals(groupResult.get("mdcs_main").toString())){//主要诊断编码不在分组范围内
				notInGroupFlag="md_diagCanNotGroup";
				return notInGroupFlag;
			}
			
			if(groupResult.get("mdcs_main")!=null&&(groupResult.get("mdcs_main").toString().contains("M"))){
				if("女".equals(mrInfoMap.get("GENDER"))){
					notInGroupFlag="s_sexErr";
					return notInGroupFlag;
				}
				boolean isContainN=false;
				List<String> adrgsMainList=(List<String>)groupResult.get("adrgs_main");
				if(adrgsMainList.size()>0){
					for(String adrgsMain:adrgsMainList){
						if("N".equals(adrgsMain.substring(0, 1))){
							isContainN=true;
							break;
						}
					}
					if(isContainN){
						notInGroupFlag="s_sexErr";
						return notInGroupFlag;
					}
				}
			}
			if(groupResult.get("mdcs_main")!=null&&(groupResult.get("mdcs_main").toString().contains("N"))){
				if("男".equals(mrInfoMap.get("GENDER"))){
					notInGroupFlag="s_sexErr";
					return notInGroupFlag;
				}
				boolean isContainM=false;
				List<String> adrgsMainList=(List<String>)groupResult.get("adrgs_main");
				if(adrgsMainList.size()>0){
					for(String adrgsMain:adrgsMainList){
						if("M".equals(adrgsMain.substring(0, 1))){
							isContainM=true;
							break;
						}
					}
					if(isContainM){
						notInGroupFlag="s_sexErr";
						return notInGroupFlag;
					}
				}
			}
			if(groupResult.get("mdcs_main")!=null&&groupResult.get("mdcs_main").toString().contains("P")){//年龄/新生儿天数、 体重等异常
				notInGroupFlag="n_ageOrWeightEtcErr";
				return notInGroupFlag;
			}
		}
		return notInGroupFlag;
	}
}
